<template>
    <div>
        <div style="padding: 10px;">
            <el-button type="primary" plain @click="zoomChange(-1)">缩小</el-button>
            <el-button type="primary" plain @click="zoomChange(1)">放大</el-button>
            <el-button type="primary" plain @click="getZoom()">当前层级</el-button>
            <el-button type="primary" plain @click="changeRotation()">视角旋转</el-button>
            <el-button type="primary" plain @click="setAttributions(1)">setAttributions</el-button>
            <el-button type="primary" plain @click="addPoint()">添加实心点</el-button>
            <el-button type="primary" plain @click="addTag()">添加图标点</el-button>
            <el-button type="primary" plain @click="addLineDefault()">添加默认配置线</el-button>
            <el-button type="primary" plain @click="addLineRed()">添加红色线</el-button>
            <el-button type="primary" plain @click="addText()">添加文字</el-button>
            <el-button type="primary" plain @click="addProvinceBorder()">省份边界</el-button>
            <el-button type="primary" plain @click="positionRect()">区域定位</el-button>
            <el-button type="primary" plain @click="addMapChart()">MapChart</el-button>
            <el-button type="primary" plain @click="addPieLayer()">PieChart</el-button>
            <el-button type="primary" plain @click="demo()">demo</el-button>
            <el-button type="primary" plain @click="addPolygon()">addPolygon</el-button>
            <el-button type="primary" plain @click="addCluster()">addCluster</el-button>
        </div>
        <div id="map" />
        <div class="chart" id="pieChart" style=" width: 100px;height:100px" />
    </div>
</template>
  
<script>
// import 'ol/ol.css';
import '../../assets/ol.css'
import OSM from 'ol/source/OSM.js';
import { Map, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
import Feature from 'ol/Feature';
import Overlay from 'ol/Overlay'
import { Point, Polygon, LineString } from 'ol/geom';
import { GeometryLayout } from 'ol/geom/Geometry';
import { Select } from 'ol/interaction'
import { pointerMove } from 'ol/events/condition';
// import GeoTIFF from 'ol/source/GeoTIFF.js';
import { fromLonLat } from 'ol/proj';
import { Attribution, defaults as defaultControls } from 'ol/control.js';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import Cluster from 'ol/source/Cluster'
import { Style, Circle, Fill, Icon, Stroke, Text } from 'ol/style';
import GeoJSON from 'ol/format/GeoJSON';
// import * as echarts from 'echarts';
// import EChartsLayer from 'ol-echarts'
export default {
    name: 'openLayerIndex',
    data() {
        return {
            map: null,
            chart: null,
            attribution: null
        }
    },
    mounted() {
        this.initMap();
        // this.initMapOSM()
    },
    methods: {
        initMap() {
            // this.attribution = new Attribution({
            //     collapsible: false,
            // });
            // 云优化地理 TIFF （COG） 的切片数据可以渲染为图层
            // const source = new GeoTIFF({
            //     sources: [
            //         {
            //             url: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/36/Q/WD/2020/7/S2A_36QWD_20200701_0_L2A/TCI.tif',
            //         },
            //     ],
            // });
            this.map = new Map({
                target: 'map',
                // interactions: new interaction().defaults({ zoom: false }),
                layers: [
                    new TileLayer({
                        source: new XYZ({
                            url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.jpg'
                            // url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}'
                        })
                    })
                    // new TileLayer({
                    //     source: source,
                    // })
                ],
                // controls: defaultControls({ attribution: false }).extend([this.attribution]),
                view: new View({
                    center: [116.403218, 39.92372],
                    zoom: 1,
                    projection: 'EPSG:4326',
                    enableZoom: false,
                    enablePan: false
                })
            });
        },
        // 需要可以访问外网才能展示地图
        initMapOSM() {
            this.map = new Map({
                target: 'map',
                layers: [
                    new TileLayer({
                        source: new OSM(),
                    }),
                ],
                view: new View({
                    center: [0, 0],
                    zoom: 2,
                }),
            });
        },
        getRandomCoordinate() {
            const minLon = -180; // 最小经度
            const maxLon = 180; // 最大经度
            const minLat = -90; // 最小纬度
            const maxLat = 90; // 最大纬度

            const lon = Math.random() * (maxLon - minLon) + minLon;
            const lat = Math.random() * (maxLat - minLat) + minLat;

            return [lon, lat];
        },
        addTag() {
            let source = new VectorSource()
            for (let i = 0; i < 1000; i++) {
                let feature = new Feature({
                    id: "ddss",
                    geometry: new Point(this.getRandomCoordinate())
                });
                feature.setStyle(
                    new Style({
                        image: new Icon({
                            anchor: [0.5, 1],
                            opacity: 1,
                            scale: 1,
                            src: require("./icon/point.png"),
                            // color: 'green'
                        }),
                        text: new Text({
                            fill: new Fill({
                                // 字体颜色
                                color: 'rgba(255,255,255,0.9)'
                            }),
                            font: '16px monospace',
                            text: '文字',
                            scale: [1, 1],
                            offsetY: -30,
                            stroke: new Stroke({ color: 'rgba(0,0,0,0.9)', width: 2 })
                        })
                    })
                );
                source.addFeature(feature)
            }
            let layer = new VectorLayer({
                opacity: 1
            })
            layer.setSource(source)
            this.map.addLayer(layer)


  
            this.map.on('pointermove', event => {
                const featureTarget = this.map.forEachFeatureAtPixel(event.pixel, feature => {
                    return feature;
                });

                source.getFeatures().forEach(feature => {
                    const originalStyle = feature.getStyle();
                    if (feature === featureTarget) {
                        originalStyle.getImage().setScale(2);
                        originalStyle.getText().setScale([1, 1])
                        featureTarget.setStyle(originalStyle);
                    } else {
                        console.log('鼠标移出');
                        originalStyle.getImage().setScale(1);
                        originalStyle.getText().setScale([0, 0])
                        feature.setStyle(originalStyle);
                    }
                });
            });
        },
        addPoint() {
            const vectorSource = new VectorSource();
            const vectorLayer = new VectorLayer({
                source: vectorSource,
            });
            this.map.addLayer(vectorLayer);

            for (let i = 0; i < 500; i++) {
                const marker = new Feature({
                    geometry: new Point(this.getRandomCoordinate()),
                });

                marker.setStyle(
                    new Style({
                        image: new Circle({
                            radius: 6,
                            fill: new Fill({ color: 'red' }),
                            stroke: new Stroke({
                                color: 'green',
                                width: 3
                            })
                        }),
                    })
                );
                vectorSource.addFeature(marker);
            }
        },
        addLineDefault() {
            let featureLine = new Feature({
                geometry: new LineString([
                    this.getRandomCoordinate(),
                    this.getRandomCoordinate(),
                ]),
            });
            let source = new VectorSource()
            source.addFeature(featureLine)
            let layer = new VectorLayer({ opacity: 1 })
            layer.setSource(source)
            this.map.addLayer(layer)
        },
        addLineRed1() {
            const vectorLayer = new VectorLayer({
                source: new VectorSource(),
                style: new Style({
                    stroke: new Stroke({
                        color: 'red',
                        width: 2
                    })
                })
            });

            // 将矢量图层添加到地图中
            this.map.addLayer(vectorLayer);

            // 创建线的坐标数组
            const coordinates = [
                this.getRandomSmallCoordinate(), // 起点坐标
                this.getRandomSmallCoordinate(), // 终点坐标
            ];

            // 创建线要素
            const lineFeature = new Feature({
                geometry: new LineString(coordinates),
            });
            // 将线要素添加到矢量图层中
            vectorLayer.getSource().addFeature(lineFeature);
            lineFeature.setStyle(new Style({
                stroke: new Stroke({
                    color: 'red',
                    width: 2
                }),
                text: new Text({
                    fill: new Fill({
                        color: 'rgba(255,255,255,0.9)'
                    }),
                    font: '16px monospace',
                    text: '线的文字',
                    scale: [0, 0],
                    stroke: new Stroke({ color: 'rgba(0,0,0,0.9)', width: 1 })
                })
            }))
            console.log(lineFeature)
            console.log(lineFeature.getStyle())
            console.log(lineFeature.getStyle().getStroke())

            const interaction = new Select({
                condition: pointerMove, // 设置条件为鼠标移动
                layers: [vectorLayer], // 设置监听的图层
                style: function () {
                    const style = lineFeature.getStyle();
                    console.log(style)

                    // 修改线的样式
                    const stroke = style.getStroke(); // 获取原有的stroke样式
                    stroke.setWidth(5)

                    // 修改文字样式
                    const text = style.getText();
                    text.setScale([1, 1]);

                    // 返回新的样式
                    return new Style({
                        stroke,
                        text
                    });
                }
            });

            // 将交互对象添加到地图上
            this.map.addInteraction(interaction);
        },
        addLineRed() {
            const vectorLayer = new VectorLayer({
                source: new VectorSource()
            });

            // 将矢量图层添加到地图中
            this.map.addLayer(vectorLayer);
            const RouterLine = [1, 2, 3, 4, 5, 6, 7]
            RouterLine.forEach(item => {
                // 创建线要素
                const lineFeature = new Feature({
                    geometry: new LineString(
                        [this.getRandomSmallCoordinate(),
                        this.getRandomSmallCoordinate()]
                    )
                });

                lineFeature.setStyle(new Style({
                    stroke: new Stroke({
                        color: 'red',
                        width: 2
                    }),
                    text: new Text({
                        fill: new Fill({
                            color: 'rgba(0,0,0,0.9)'
                        }),
                        font: '16px monospace',
                        text: "---" + item + "---",
                        scale: [0, 0],
                        stroke: new Stroke({ color: 'rgba(0,0,0,0.9)', width: 1 })
                    })
                }))
                // 将线要素添加到矢量图层中
                vectorLayer.getSource().addFeature(lineFeature);

                // 鼠标移入事件 暂时不需要
                const interaction = new Select({
                    condition: pointerMove, // 设置条件为鼠标移动
                    layers: [vectorLayer], // 设置监听的图层
                    style: function () {
                        try {
                            const style = lineFeature.getStyle();

                            // 修改线的样式
                            const stroke = style.getStroke(); // 获取原有的stroke样式
                            stroke.setWidth(5)

                            // 修改文字样式
                            const text = style.getText();
                            text.setScale([1, 1]);

                            // 返回新的样式
                            return new Style({
                                stroke,
                                text
                            });
                        } catch (e) {
                            return new Style({
                                stroke: new Stroke({
                                    color: 'red',
                                    width: 2
                                }),
                                text: new Text({
                                    fill: new Fill({
                                        color: 'rgba(0,0,0,0.9)'
                                    }),
                                    font: '16px monospace',
                                    text: "---" + item + "---",
                                    scale: [0, 0],
                                    stroke: new Stroke({ color: 'rgba(0,0,0,0.9)', width: 1 })
                                })
                            })
                        }
                    }
                });
                // 将交互对象添加到地图上
                this.map.addInteraction(interaction);
            })
        },
        addText() {
            // 创建绘制文字的矢量图层
            const vectorLayer = new VectorLayer({
                source: new VectorSource(),
                style: new Style({
                    text: new Text({
                        font: '16px monospace',
                        fill: new Fill({
                            color: '#000'
                        }),
                        stroke: new Stroke({
                            color: '#fff',
                            width: 3
                        })
                    })
                })
            });

            // 将矢量图层添加到地图中
            this.map.addLayer(vectorLayer);

            // 创建文字要素
            const textFeature = new Feature({
                geometry: new Point([116.403218, 39.92372]),
                text: 'Hello OpenLayers'
            });

            // 设置文字要素样式
            // textFeature.getStyle().getText().setTextBaseline('bottom');
            // textFeature.getStyle().getText().setTextAlign('center');

            // 将文字要素添加到矢量图层中
            vectorLayer.getSource().addFeature(textFeature);
        },
        addProvinceBorder() {


            let changsha = require('./mapJson/changsha.json');
            let hunan = require('./mapJson/hunan.json');
            let wuhan = require('./mapJson/wuhan.json');
            let jiangxi = require('./mapJson/jiangxi.json');
            let guangdong = require('./mapJson/guangdong.json');
            let guangxi = require('./mapJson/guangxi.json');
            let chongqing = require('./mapJson/chongqing.json');

            const allJson = [
                {
                    id: 'changsha',
                    json: changsha
                },
                // {
                //     id: 'hunan',
                //     json: hunan
                // },
                {
                    id: 'wuhan',
                    json: wuhan
                },
                {
                    id: 'jiangxi',
                    json: jiangxi
                },
                {
                    id: 'guangdong',
                    json: guangdong
                },
                {
                    id: 'guangxi',
                    json: guangxi
                },
                {
                    id: 'chongqing',
                    json: chongqing
                }
            ]

            allJson.forEach(item => {
                let features = new GeoJSON().readFeatures(item.json)
                var vectorSource = new VectorSource({ features: features });
                let lineLayer = new VectorLayer({
                    id: item.id,
                    name: 'hunan border',
                    opacity: 1,
                    zIndex: 1,
                    source: vectorSource,
                    style: new Style({
                        stroke: new Stroke({
                            color: 'red',
                            width: 1
                        }),
                        fill: new Fill({
                            color: 'rgba(0, 255, 255, 0.5)',
                        }),
                    })
                })
                this.map.addLayer(lineLayer)
            })

        },
        addPieChart() {
            var data = [{ name: 'A', value: 20 }, { name: 'B', value: 23 }, { name: 'C', value: 45 }, { name: 'D', value: 34 }, { name: 'E', value: 14 }]
            var option = {
                tooltip: {
                    trigger: 'item',
                    formatter: '{b} : {c} ({d}%)'
                },
                toolbox: {
                    show: true,
                    feature: {
                        mark: { show: true },
                        magicType: {
                            show: true,
                            type: ['pie', 'funnel']
                        }
                    }
                },
                calculable: true,
                series: [{
                    type: 'pie',
                    radius: '60%',
                    startAngle: '45',
                    label: {
                        normal: {
                            show: false
                        },
                        emphasis: {
                            show: false,
                            textStyle: {
                                color: '#000000',
                                fontWeight: 'bold',
                                fontSize: 16
                            }
                        }
                    },
                    lableLine: {
                        normal: {
                            show: false
                        },
                        emphasis: {
                            show: false
                        }
                    },
                    data: data
                }]
            }
            const pieChart = echarts.init(document.getElementById('pieChart'))
            pieChart.setOption(option)
        },
        addPieLayer() {
            this.addPieChart()
            // 创建Overlay弹出层绑定DOM
            const overlay = new Overlay({
                element: document.getElementById('pieChart'),
                autoPan: {
                    animation: {
                        duration: 250
                    }
                },
                position: this.getRandomCoordinate(),
                positioning: 'center-center'
            })
            // 添加到map
            this.map.addOverlay(overlay)
        },
        addPolygon() {
            const vectorSource = new VectorSource();
            const vectorLayer = new VectorLayer({
                source: vectorSource,
            });
            this.map.addLayer(vectorLayer);
            const coordinates = [
                this.getRandomCoordinate(), this.getRandomSmallCoordinate(), this.getRandomSmallCoordinate(),
                this.getRandomSmallCoordinate(), this.getRandomCoordinate(),
            ];
            const polygonGeometry = new Polygon([coordinates]);

            const polygonFeature = new Feature(polygonGeometry);

            polygonFeature.setStyle(new Style({
                stroke: new Stroke({
                    color: 'red',
                    width: 2,
                    // lineDash: [10, 5] 
                }),
                fill: new Fill({
                    color: 'rgba(255,255,0,0.7)'
                }),
            }))

            vectorSource.addFeature(polygonFeature);
        },
        initChartMap(dataGeo, lineData) {
            return {
                color: ['#5470c6'],
                tooltip: {
                    trigger: 'item',
                    renderMode: 'html',
                    // 触发方式
                    triggerOn: 'click',
                    enterable: true,
                    backgroundColor: '#fff',
                    padding: 0,
                    textStyle: {
                        color: '#000',
                        fontSize: '12'
                    },
                    extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);'
                },
                dispatchAction: {
                    type: 'downplay'
                },
                roam: false,
                roamController: {
                    show: true,
                    x: 'right',
                    mapTypeControl: {
                        china: true
                    }
                },
                series: [{
                    name: '',
                    type: 'scatter',
                    coordinateSystem: 'geo',
                    color: ['#000'],
                    tooltip: {
                        position: "right",
                        color: "#000",
                        formatter(d) {
                            console.log(d)
                            return `<div style="padding: 5px 10px;">【${d.data.name}】</div>`;
                        },
                    },
                    data: dataGeo,
                },
                {
                    name: "",
                    type: "lines",
                    zlevel: 6,
                    lineStyle: {
                        type: 'solid',
                        width: 1,
                        opacity: 1,
                        curveness: 0,
                        orient: 'horizontal',
                        color: "#000",
                    },
                    show: true,
                    data: lineData,
                    tooltip: {
                        position: "right",
                        color: "#000",
                        formatter(d) {
                            console.log(d)
                            return `<div style="padding: 5px 10px;"> 【${d.data.point[0]}】< ---- >【${d.data.point[1]}】</div>`;
                        },
                    },
                },
                ],
                geo: {
                    show: true,
                    map: 'anhui',
                    type: 'map',
                    mapType: 'anhui',
                    roam: false,
                    label: {
                        normal: {
                            // 显示省份标签
                            show: false,
                            textStyle: {
                                color: '#fff',
                                fontSize: 10
                            }
                        },
                        emphasis: {
                            // 对应的鼠标悬浮效果
                            show: true,
                            // 选中后的字体样式
                            textStyle: {
                                color: '#000',
                                fontSize: 14
                            }
                        }
                    },
                    itemStyle: {
                        color: '#ddb926',
                        normal: {
                            areaColor: '#8abcd1',
                            borderColor: '#fff',
                            borderWidth: 1
                        },
                        emphasis: {
                            borderWidth: 0.5,
                            borderColor: '#8abcd1',
                            areaColor: '#fff'
                        }
                    },
                    emphasis: {
                        label: {
                            show: false
                        }
                    }
                }
            }

        },
        addMapChart() {
            let mapPointData = []
            mapPointData.push({
                name: '六安',
                value: [116.50, 31.75]
            })
            mapPointData.push({
                name: '马鞍山',
                value: [118.51, 31.68]
            })
            mapPointData.push({
                name: '宿州',
                value: [116.98, 33.63]
            })

            let lineData = []
            lineData.push({
                point: ['六安', '马鞍山'],
                coords: [
                    [116.50, 31.75],
                    [118.51, 31.68]
                ],
            })
            lineData.push({
                point: ['宿州', '马鞍山'],
                coords: [
                    [116.98, 33.63],
                    [118.51, 31.68]
                ],
            })
            lineData.push({
                point: ['宿州', '六安'],
                coords: [
                    [116.98, 33.63],
                    [116.50, 31.75]
                ],
            })

            const option = this.initMap(mapPointData, lineData)
            this.echartsLayer = new EChartsLayer(option, {
                hideOnMoving: true,
                hideOnZooming: false,
                forcedPrecomposeRerender: false
            })
            // 加进去即可
            this.echartsLayer.appendTo(this.map)
        },
        // 地图放大与缩小
        zoomChange(num) {
            const view = this.map.getView();
            const zoom = view.getZoom();
            const duration = 1000;

            view.animate({
                zoom: zoom + num,

                duration
            });
        },
        getZoom() {
            this.$message({
                message: `当前层级：${this.map.getView().getZoom().toFixed(2)} ---  当前中心点 ${this.map.getView().getCenter()}`,
                type: 'success'
            });
        },
        positionRect() {
            const bounds = [116, 28, 125, 34]
            const width = this.map.getSize()[0];
            const height = this.map.getSize()[1];

            // 将地图视图聚焦至初始范围
            this.map.getView().fit(bounds, {
                size: [width, height],
                padding: [5, 5, 5, 5],
                minResolution: 0,
                duration: 4000,
                easing: function (t) {
                    return 1 - Math.pow(1 - t, 2);
                }
            });
        },
        setAttributions() {
            this.attribution.setCollapsible(true);
            this.attribution.setCollapsed(true);
        },
        changeRotation() {
            const view = this.map.getView();
            view.animate({
                rotation: Math.PI / 3,
                duration
            })
        },
        getRandomSmallCoordinate() {
            const minLon = 0; // 最小经度
            const maxLon = 90; // 最大经度
            const minLat = 0; // 最小纬度
            const maxLat = 20; // 最大纬度

            const lon = Math.random() * (maxLon - minLon) + minLon;
            const lat = Math.random() * (maxLat - minLat) + minLat;

            return [lon, lat];
        },
        demo() {
            const vectorLayer = new VectorLayer({
                source: new VectorSource(),
            });

            // 将矢量图层添加到地图中
            this.map.addLayer(vectorLayer);

            for (let i = 0; i < 10; i++) {
                // 创建线的坐标数组
                const coordinates = [
                    this.getRandomSmallCoordinate(), // 起点坐标
                    this.getRandomSmallCoordinate(), // 终点坐标
                ];

                // 创建线要素
                const lineFeature = new Feature({
                    geometry: new LineString(coordinates)
                });

                lineFeature.setStyle(new Style({
                    stroke: new Stroke({
                        color: 'red',
                        width: 2
                    }),
                    text: new Text({
                        text: 'A',
                        font: '20px', // 设置字体样式
                        fill: new Fill({ color: 'black' }), // 设置字体颜色
                        stroke: new Stroke({ color: 'white', width: 3 }), // 设置边框颜色和宽度
                        padding: [5, 5, 5, 5] // 设置内边距
                    })
                }))
                // 将线要素添加到矢量图层中
                vectorLayer.getSource().addFeature(lineFeature);
            }
        },
        addCluster() {
            const vectorSource = new VectorSource();
            for (let i = 0; i < 1000; i++) {
                // 创建一个点要素并添加到矢量源中
                const pointFeature = new Feature({
                    geometry: new Point(this.getRandomSmallCoordinate()), // 替换为实际的经纬度
                });
                pointFeature.setStyle(
                    new Style({
                        image: new Circle({
                            radius: 6,
                            fill: new Fill({ color: 'red' }),
                            stroke: new Stroke({
                                color: 'green',
                                width: 3
                            })
                        }),
                        text: new Text({
                            text: 'A'
                        })
                    })
                );
                console.log(pointFeature)
                vectorSource.addFeature(pointFeature);
            }
            const clusterSource = new Cluster({
                distance: 40, // 聚合的距离阈值，单位为像素
                source: vectorSource,
            });
            const vectorLayer = new VectorLayer({
                source: clusterSource,
            });
            // vectorLayer.setStyle(
            //     new Style({
            //         image: new Circle({
            //             radius: 6,
            //             fill: new Fill({ color: 'red' }),
            //             stroke: new Stroke({
            //                 color: 'green',
            //                 width: 3
            //             })
            //         }),
            //     })
            // );
            this.map.addLayer(vectorLayer)
        }
    }
};
</script>

<style scoped>
#map {
    width: 100%;
    height: 800px;
}
</style>
  